package com.zhaojie.savemoney.ui;

import android.app.DatePickerDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.zhaojie.savemoney.R;
import com.zhaojie.savemoney.data.CostDataManager;
import com.zhaojie.savemoney.model.CostType;
import com.zhaojie.savemoney.ui.customview.CommonTitleBar;
import com.zhaojie.savemoney.ui.customview.SimpleCostListFragment;
import com.zhaojie.tablayout.OnTabSelectListener;
import com.zhaojie.tablayout.SegmentTabLayout;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link CostListFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link CostListFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class CostListFragment extends Fragment implements DatePickerDialog.OnDateSetListener {
    private static final String TAG = "CostListFragment";

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private View rootView;
    @Bind(R.id.title_layout)
    CommonTitleBar titleBar;
    @Bind(R.id.costlist_tab)
    SegmentTabLayout costlistTab;
    @Bind(R.id.costlist_vp)
    ViewPager costlistVp;
    @Bind(R.id.costlist_date)
    LinearLayout costlistDate;
    @Bind(R.id.costlist_date_year)
    TextView costlistDateYear;
    @Bind(R.id.costlist_date_month)
    TextView costlistDateMonth;
    @Bind(R.id.costlist_output_total)
    TextView costlistOutputTotal;
    @Bind(R.id.costlist_input_total)
    TextView costlistInputTotal;

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    private int[] mTitles = {
            R.string.costlist_all,
            R.string.costlist_output,
            R.string.costlist_input};
    private int[] mTypeKinds = {
            CostType.INPUT_KIND + CostType.OUTPUT_KIND,
            CostType.OUTPUT_KIND,
            CostType.INPUT_KIND
    };

    private ArrayList<Fragment> listFragments = new ArrayList<>();

    public CostListFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment CostListFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static CostListFragment newInstance(String param1, String param2) {
        CostListFragment fragment = new CostListFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        costlistInputTotal.setText(String.format("%.1f", CostDataManager.getInstance().getTotalInputValue()));
        costlistOutputTotal.setText(String.format("%.1f", CostDataManager.getInstance().getTotalOutputValue()));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_cost_list, container, false);
        ButterKnife.bind(this, rootView);
        initViews();
        initEvent();
        return rootView;
    }

    private void initViews() {
        String titleStr[] = new String[mTitles.length];
        int index = 0;
        for (int id : mTitles) {
            titleStr[index] = getString(id);
            listFragments.add(SimpleCostListFragment.getInstance(getString(id), mTypeKinds[index]));
            index++;
        }
        costlistTab.setTabData(titleStr);

        costlistVp.setAdapter(new CostListPagerAdapter(getFragmentManager()));
        costlistVp.setCurrentItem(0);
        costlistTab.setCurrentTab(0);
    }

    private void initEvent() {
        Log.d(TAG, "initEvent:" + mListener);
        titleBar.setLeftBtnOnclickListener(v1 -> {
            mListener.onMenuClicked();
        });

        costlistTab.setOnTabSelectListener(new OnTabSelectListener() {
            @Override
            public void onTabSelect(int position) {
                costlistVp.setCurrentItem(position, true);

            }

            @Override
            public void onTabReselect(int position) {

            }
        });

        costlistVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                costlistTab.setCurrentTab(position);

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        costlistDate.setOnClickListener(v -> {
            Calendar now = Calendar.getInstance();
            Date myDate = new Date();
            now.setTime(myDate);
            int year = now.get(Calendar.YEAR);
            int month = now.get(Calendar.MONTH);
            int day = now.get(Calendar.DAY_OF_MONTH);
            DatePickerDialog dpd = new DatePickerDialog(getActivity(), this, year, month, day);
            dpd.show();
        });
    }

    @Override
    public void onAttach(Context context) {
        Log.d(TAG, "onAttach");
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
        Log.d(TAG, "onAttach:" + mListener);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        costlistDateYear.setText(String.valueOf(year));
        costlistDateMonth.setText(String.format("%02d月", monthOfYear + 1));
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        void onMenuClicked();
    }

    private class CostListPagerAdapter extends PagerAdapter {
        private static final String TAG = "FragmentPagerAdapter";
        private static final boolean DEBUG = false;

        private final FragmentManager mFragmentManager;
        private FragmentTransaction mCurTransaction = null;
        private Fragment mCurrentPrimaryItem = null;

        public CostListPagerAdapter(FragmentManager fm) {
            mFragmentManager = fm;
        }

        /**
         * Return the Fragment associated with a specified position.
         */
        public Fragment getItem(int position) {
            return listFragments.get(position);
        }

        @Override
        public int getCount() {
            return listFragments.size();
        }

        @Override
        public void startUpdate(ViewGroup container) {
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            if (mCurTransaction == null) {
                mCurTransaction = mFragmentManager.beginTransaction();
            }

            final long itemId = getItemId(position);

            // Do we already have this fragment?
            String name = makeFragmentName(container.getId(), itemId);
            Fragment fragment = mFragmentManager.findFragmentByTag(name);
            if (fragment != null) {
                if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
                mCurTransaction.attach(fragment);
            } else {
                fragment = getItem(position);
                if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
                mCurTransaction.add(container.getId(), fragment,
                        makeFragmentName(container.getId(), itemId));
            }
            if (fragment != mCurrentPrimaryItem) {
                fragment.setMenuVisibility(false);
                fragment.setUserVisibleHint(false);
            }

            return fragment;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            if (mCurTransaction == null) {
                mCurTransaction = mFragmentManager.beginTransaction();
            }
            if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
                    + " v=" + ((Fragment) object).getView());
            mCurTransaction.detach((Fragment) object);
        }

        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            Fragment fragment = (Fragment) object;
            if (fragment != mCurrentPrimaryItem) {
                if (mCurrentPrimaryItem != null) {
                    mCurrentPrimaryItem.setMenuVisibility(false);
                    mCurrentPrimaryItem.setUserVisibleHint(false);
                }
                if (fragment != null) {
                    fragment.setMenuVisibility(true);
                    fragment.setUserVisibleHint(true);
                }
                mCurrentPrimaryItem = fragment;
            }
        }

        @Override
        public void finishUpdate(ViewGroup container) {
            if (mCurTransaction != null) {
                mCurTransaction.commitAllowingStateLoss();
                mCurTransaction = null;
                mFragmentManager.executePendingTransactions();
            }
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return ((Fragment) object).getView() == view;
        }

        @Override
        public Parcelable saveState() {
            return null;
        }

        @Override
        public void restoreState(Parcelable state, ClassLoader loader) {
        }

        /**
         * Return a unique identifier for the item at the given position.
         * <p>
         * <p>The default implementation returns the given position.
         * Subclasses should override this method if the positions of items can change.</p>
         *
         * @param position Position within this adapter
         * @return Unique identifier for the item at position
         */
        public long getItemId(int position) {
            return position;
        }

        private String makeFragmentName(int viewId, long id) {
            return "android:switcher:" + viewId + ":" + id;
        }
    }
}
